﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Media.Animation;

namespace Gmantis.Controls.DataGrid
{
    [TemplatePart(Name = "Watermark", Type = typeof(FrameworkElement))]
    public class DataGridNewRowPresenter : DataGridSelectableRowPresenter
    {
        // Fields
        internal FrameworkElement _elementWatermark;
        internal const string WatermarkElementName = "Watermark";
        public static readonly DependencyProperty WatermarkTextProperty = DependencyProperty.Register("WatermarkText", typeof(string), typeof(DataGridNewRowPresenter), new PropertyMetadata("Click here to add a new row"));

        // Methods
        public DataGridNewRowPresenter()
        {
            base.DefaultStyleKey = typeof(DataGridNewRowPresenter);
            this.SetCustomDefaultValues();
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        protected internal override void Load()
        {
            base.Load();
            if (base.Row is DataGridNewRow)
            {
                DataGridNewRow row = base.Row as DataGridNewRow;
                row.IsEnteringNewRowChanging += new EventHandler<PropertyChangedEventArgs<bool>>(this.row_IsEnteringNewRowChanging);
                row.IsEnteringNewRowChanged += new EventHandler<PropertyChangedEventArgs<bool>>(this.row_IsEnteringNewRowChanged);
                this.UpdateIsEnteringNewRow();
            }
        }

        private void OnAfterApplyTemplate()
        {
            this.UpdateIsEnteringNewRow();
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._elementWatermark = this.GetTemplateChild<FrameworkElement>("Watermark", true, ref errors);
            if (!string.IsNullOrEmpty(errors))
            {
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGridNewRowPresenter.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.OnAfterApplyTemplate();
            }
        }

        private void row_IsEnteringNewRowChanged(object sender, PropertyChangedEventArgs<bool> e)
        {
            this.UpdateIsEnteringNewRow();
        }

        private void row_IsEnteringNewRowChanging(object sender, PropertyChangedEventArgs<bool> e)
        {
            if (!e.NewValue && (base.CellsPanel != null))
            {
                base.CellsPanel.RemoveChildren();
            }
        }

        private void SetCustomDefaultValues()
        {
        }

        protected internal override void Unload()
        {
            base.Unload();
            if (base.Row is DataGridNewRow)
            {
                DataGridNewRow row = base.Row as DataGridNewRow;
                row.IsEnteringNewRowChanging -= new EventHandler<PropertyChangedEventArgs<bool>>(this.row_IsEnteringNewRowChanging);
                row.IsEnteringNewRowChanged -= new EventHandler<PropertyChangedEventArgs<bool>>(this.row_IsEnteringNewRowChanged);
            }
        }

        private void UpdateIsEnteringNewRow()
        {
            DataGridNewRow row = base.Row as DataGridNewRow;
            if (row.IsEnteringNewRow)
            {
                base.InvalidateCellsMeasure();
            }
            if (base._elementCells != null)
            {
                base._elementCells.Opacity = row.IsEnteringNewRow ? ((double)1) : ((double)0);
                this._elementWatermark.Opacity = row.IsEnteringNewRow ? ((double)0) : ((double)1);
            }
        }

        // Properties
        public string WatermarkText
        {
            get
            {
                return (string)base.GetValue(WatermarkTextProperty);
            }
            set
            {
                base.SetValue(WatermarkTextProperty, value);
            }
        }
    }
}
